# code=utf-8
#
import ephem
from ephem import _sun
from math import *
from decimal import *
import datetime

'''
春季:立春（315度）、雨水（330度）、惊蛰（345度）、春分（360or0 2 * pi, 0）、清明（15度）和谷雨（30度）
夏季:立夏（45度）、小满（60度）、芒种（75度）、夏至（ 90 2 * pi, 1.5 * pi）、小暑（105度）和大暑（120度）
秋季:立秋（135度）、处暑（150度）、白露（165度）、秋分（180度）、寒露（195度）和霜降（210度）
冬季:立冬（225度）、小雪（240度）、大雪（255度）、冬至（270度）、小寒（285度）和大寒（300度）
'''


def CalculateSolarTerms(year, angle):
    JD0 = 0.00000000000000000000000000000000
    JD1 = 0.00000000000000000000000000000000
    JD1 = float(get_initial_estimate_solar_terms(year, angle))
    while ((fabs(JD1 - JD0) > 0.0000001)):
        JD0 = JD1
        stDegree = get_sun_ecliptic_longitude_ec(JD0)  # 日黄纬
        # 对黄经度迭代逼近时，由于角度度圆周性，估算黄经值可能在(345,360)和(0,15)两个区间，如果值落入前*/
        stDegree = stDegree - 360.0 if ((angle == 0) or (stDegree > 345.0)) else stDegree
        stDegreep = (get_sun_ecliptic_longitude_ec(JD0 + 0.000005) - get_sun_ecliptic_longitude_ec(
            JD0 - 0.000005)) / 0.00001
        JD1 = JD0 - (stDegree - angle) / stDegreep
        print(str(JD1 - JD1 - 0.0000001))
    return JD1


def get_sun_ecliptic_longitude_ec(JD):
    sun = _sun
    sun.compute(JD)
    return ephem.Ecliptic(sun).lon


def get_initial_estimate_solar_terms(year, angle):
    STMonth = int(ceil((angle + 90.0) / 30.0))
    STMonth = (STMonth - 12) if STMonth > 12 else  STMonth
    # /* 每月第一个节气发生日期基本都-9日之间，第二个节气的发生日期都在-日之间*/
    if ((angle % 15 == 0) and (angle % 30 != 0)):
        return ephem.julian_date((year, STMonth, 6, 12, 0, 0.00))
    else:
        return ephem.julian_date((year, STMonth, 20, 12, 0, 0.00))


def is_gregorian_days(year, month, day):
    """判断是否是格林历法，这里按照罗马教皇的时间安排方式"""
    if year == 1582 and month == 10:
        if 5 < day >= 15:
            return False
        else:
            return True
    else:
        return True


def calculate_day(JD):
    a = int(JD + 0.5)

    b = a + 1537

    c = int((b - 122.1) / 365.25)

    d = int(365.25*c)

    e = int((b - d) / 30.6001)

    D = b - d - int(30.6001 * e) + (JD + 0.5)

    M = e - 1 - 12 * int(e / 14)

    Y = c - 4715 - int((7 + M) / 10)
    return str(Y) + "n" +str(M) + "n"+str(D) + "D"


def calculate_julian_day(year, month, day, hour, minute, second):
    """
    计算儒略历时间
    儒略历定义：公元前4713年1月1日 UTC 12:00开始所经过的天数，
    JD0就被指定为公元前4713年1月1日 12:00到公元前4713年1月 2日12:00之间的24小时
    """
    a = int((14 - month) / 12)
    y = year + 4800 - a
    m = month + 12 * a - 3
    jdn = day + int((153 * m + 2) / 5) + 365 * y + int(y / 4)
    if is_gregorian_days(year, month, day):
        jdn = jdn - int(y / 100) + int(y / 400) - 32045.5
    else:
        jdn -= 32083.5
    return jdn + hour / 24.0 + minute / 1440.0 + second / 86400.0


if __name__ == '__main__':
    # # 立春
    # print(ephem.holiday('2016', 2 * pi, (360-315) * pi / 180 ))
    # # 春分
    # print(ephem.localtime(ephem.holiday('2016', 2 * pi, (360 - 360) * pi / 180)))
    # # 立夏
    # print(ephem.localtime(ephem.holiday('2016', 2 * pi, (360 - 45) * pi / 180)))
    # # 冬至
    # print(ephem.holiday('2016', 2 * pi, (360 - 270) * pi / 180))
    #
    # print(ephem.previous_equinox('2017'))
    # print(ephem.previous_winter_solstice('2016')) # 12月
    # print(ephem.next_new_moon(ephem.previous_winter_solstice('2016')))
    # print(ephem.next_new_moon('2016-2-1')) # 第一个新月
    # print(ephem.next_new_moon(ephem.next_new_moon('2016-2-1'))) # 第一个新月
    # print(ephem.next_new_moon(ephem.next_new_moon('2016-2-1'))-ephem.next_new_moon('2016-2-1')) # 第一个新月

    # print(CalculateSolarTerms(2016,345))
    # print(float(get_initial_estimate_solar_terms(2016, 345)))
    print(calculate_julian_day(1582, 10, 5, 12, 0, 0))
    print(calculate_julian_day(1582, 10, 15, 12, 0, 0))
    print(calculate_julian_day(1582, 10, 11, 12, 0, 0))
    print(calculate_day(2299151.0))
